home *** CD-ROM | disk | FTP | other *** search
- /* AutoCAD DXF file to DKB Data File Converter */
- /* Version 1.0 By Aaron A. Collins. Written 8/13/90 */
- /* Version 1.01 Modified to work with DKB 2.10 By Drew Wells 3/20/91 */
- /* This program is released to the public domain. */
- /*--------------------------------------------------------------------*/
- /* Version History */
- /*--------------------------------------------------------------------*/
- /* 8/19/90 AC Wrote original program.
- * 3/20/91 DW Put colors inside texture block for DKB 2.10.
- * DW Removed line INCLUDE "Basicshapes.dat".
- * DW Added additional comment docs at top of DKB outfile.
- * DW Added additional stats as to what DXF types were found.
- * 4/29/91 AC Modified usage message and header semantics a bit.
- * 5/15/91 AC Removed IBM-ness of filenames/extensions
- */
-
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
-
- #define BUFSIZE 2048
- #define FABS(x) ((x<0.0)?-x:x)
-
- int getline (void);
- void writeobj (void);
- void finishobj (int color);
- void lookupcolor (int color, double *red, double *green, double *blue);
- int checkdegen(int a, int b, int c);
-
- int groupcode;
- char linbuf[BUFSIZE];
- FILE *infile, *outfile;
- long primitives = 0L, degenerates = 0L;
- long num_triangles = 0L, num_points = 0L, num_circles = 0L, num_traces = 0L,
- num_solids = 0L, num_lines = 0L, num_3dlines = 0L, num_3dfaces = 0L;
- char curobj[80];
- int curcolor;
- double curthick;
- double xcoords[10];
- double ycoords[10];
- double zcoords[10];
- double doubles[10];
- double angles[10];
- int ints[10];
- double max_x, max_y, max_z, min_x, min_y, min_z;
-
-
- void main(argc, argv)
- int argc;
- char *argv[];
- {
- char *index;
-
- printf("\n\nAutoCad DXF to DKB Data file Translator\n");
- printf("Version 1.0 Written By Aaron A. Collins, 8/13/90\n");
- printf("Version 1.01 Modifications By Drew Wells 3/20/91\n");
- printf("Version 1.02 Modifications By Aaron A. Collins 3/20/91\n");
- printf("Version 1.03 Modifications By Aaron A. Collins 5/15/91\n");
- printf("* Type DXF2DKB with no arguments for more info. *\n");
- printf("This program is released to the public domain.\n\n");
- if (argc != 3)
- {
- printf("Usage: %s InputFile OutputFile\n\n", argv[0]);
-
- printf("DXF2DKB does a minimal conversion of AutoCad DXF files into DKB data format.\n");
- printf("The following DXF primitives are currently supported:\n");
- printf("\t3D Faces\tTriangles\tPoints\n");
- printf("\t3D Lines\tCircles \tSolids\n");
- printf("\tLines \tTraces\n");
- printf("The DKB Raytracer is available on Compuserve's COMART forum lib 16 and\n");
- printf("The \"You Can Call Me RAY\" Raytracing BBS at (708) 358-5611.\n");
- printf("C source code for this utility is also available at those locations.\n");
-
- exit(1);
- }
- if (!(infile = fopen(argv[1], "r")))
- {
- printf("Cannot open input file %s!\n", argv[1]);
- exit(1);
- }
-
- if (!(outfile = fopen(argv[2], "w")))
- {
- printf("Cannot create output file %s!\n", argv[2]);
- fclose(infile);
- exit(1);
- }
-
- printf("\nPlease wait; Processing...");
- fprintf(outfile, "{ This file is for use with the DKB Ray Tracer.}\n");
- fprintf(outfile, "{ %s: Converted from AutoCad DXF File: %s }\n\n", argv[2], argv[1]);
- fprintf(outfile, "{ This is a composite object description for use with the DKB }\n");
- fprintf(outfile, "{ Ray Tracer. It does not include viewpoint or light source desc-}\n");
- fprintf(outfile, "{ riptions. It uses the Dull texture from textures.dat and it }\n");
- fprintf(outfile, "{ may use Cylinder_Z from shapes.dat. }\n");
- fprintf(outfile, "{ To use this file as an include file uncomment the DECLARE line }\n");
- fprintf(outfile, "{ and change DxfObject to an appropriate name.}\n\n");
- fprintf(outfile, "INCLUDE \"shapes.dat\"\n");
- fprintf(outfile, "INCLUDE \"colors.dat\"\n");
- fprintf(outfile, "INCLUDE \"textures.dat\"\n\n");
- fprintf(outfile, "{ DECLARE DxfObject = }\n",argv[2]);
-
- fprintf(outfile, "COMPOSITE\n");
-
- curobj[0] = '\0'; /* not working on any object currently */
- curcolor = 7; /* and it also doesn't have a color yet... */
- max_x = max_y = max_z = -10000000.0; /* init bounding limits */
- min_x = min_y = min_z = 10000000.0;
-
- find: while (!feof(infile)) /* run file up to the "ENTITIES" section */
- {
- if (getline()) /* get a group code and a line */
- goto stopit;
- if (groupcode == 0) /* file section mark */
- {
- if (strstr(linbuf, "EOF"))
- goto stopit;
- if (strstr(linbuf, "SECTION"))
- {
- if (getline())
- goto stopit;
- if (groupcode != 2)
- continue;
- if (strstr(linbuf, "ENTITIES"))
- break;
- }
- }
- }
- while (!feof(infile)) /* scan ENTITIES section */
- {
- if (getline()) /* get a group code and a line */
- break;
- if (groupcode < 10) /* cardinal group codes */
- {
- switch(groupcode)
- {
- case 0: /* start of entity, table, file sep */
- if (strstr(linbuf, "EOF"))
- {
- writeobj(); /* dump object */
- goto stopit;
- }
- if (strstr(linbuf, "ENDSEC"))
- {
- writeobj(); /* dump object */
- goto find;
- }
- writeobj(); /* dump old object */
- curobj[0] = '\0'; /* reset object */
- curcolor = 7;
- strcpy(curobj, linbuf); /* get new */
- break;
- case 1: /* primary text value for entity (?)*/
- break;
- case 2: /* block name, attribute tag, etc */
- case 3: /* other names */
- case 4:
- break;
- case 5: /* entity handle (hex string) */
- break;
- case 6: /* line type name */
- break;
- case 7: /* text style name */
- break;
- case 8: /* layer name */
- break;
- case 9: /* variable name ID (only in header)*/
- break;
- }
- }
- else if (groupcode >= 10 && groupcode < 19) /* Some X coord */
- {
- sscanf(linbuf, "%f", &(xcoords[groupcode-10]));
- if (xcoords[groupcode-10] > max_x)
- max_x = xcoords[groupcode-10];
- if (xcoords[groupcode-10] < min_x)
- min_x = xcoords[groupcode-10];
- }
- else if (groupcode >= 20 && groupcode < 29) /* Some Y coord */
- {
- sscanf(linbuf, "%f", &(ycoords[groupcode-20]));
- if (ycoords[groupcode-20] > max_y)
- max_y = ycoords[groupcode-20];
- if (ycoords[groupcode-20] < min_y)
- min_y = ycoords[groupcode-20];
- }
- else if (groupcode >= 30 && groupcode < 38) /* Some Z coord */
- {
- sscanf(linbuf, "%f", &(zcoords[groupcode-30]));
- if (zcoords[groupcode-30] > max_z)
- max_z = zcoords[groupcode-30];
- if (zcoords[groupcode-30] < min_z)
- min_z = zcoords[groupcode-30];
- }
- else if (groupcode == 38) /* entity elevation if nonzero */
- {
- }
- else if (groupcode == 39) /* entity thickness if nonzero */
- {
- }
- else if (groupcode >= 40 && groupcode < 49) /* misc doubles */
- {
- sscanf(linbuf, "%f", &(doubles[groupcode-40]));
- }
- else if (groupcode == 49) /* repeated value groups */
- {
- }
- else if (groupcode >= 50 && groupcode < 59) /* misc angles */
- {
- sscanf(linbuf, "%f", &(angles[groupcode-50]));
- }
- else if (groupcode == 62) /* Color number */
- {
- sscanf(linbuf, "%6d", &curcolor);
- }
- else if (groupcode == 66) /* "entities follow" flag */
- {
- }
- else if (groupcode >= 70 && groupcode < 79) /* misc ints */
- {
- sscanf(linbuf, "%f", &(ints[groupcode-70]));
- }
- else if (groupcode == 210 || groupcode == 220 || groupcode == 230)
- { /* X, Y, Z components of extrusion direction */
- }
- }
- stopit: fprintf(outfile, " BOUNDED_BY\n INTERSECTION\n");
- fprintf(outfile, " PLANE <1.0 0.0 0.0> %1.04f END_PLANE\n", FABS(max_x) * 1.01);
- fprintf(outfile, " PLANE <-1.0 0.0 0.0> %1.04f END_PLANE\n", FABS(min_x) * 1.01);
- fprintf(outfile, " PLANE <0.0 1.0 0.0> %1.04f END_PLANE\n", FABS(max_y) * 1.01);
- fprintf(outfile, " PLANE <0.0 -1.0 0.0> %1.04f END_PLANE\n", FABS(min_y) * 1.01);
- fprintf(outfile, " PLANE <0.0 0.0 1.0> %1.04f END_PLANE\n", FABS(max_z) * 1.01);
- fprintf(outfile, " PLANE <0.0 0.0 -1.0> %1.04f END_PLANE\n", FABS(min_z) * 1.01);
- fprintf(outfile, " END_INTERSECTION\n END_BOUND\nEND_COMPOSITE\n");
- fclose(infile);
- fflush(outfile);
- fclose(outfile);
- printf("Finished.\nTotal DKB objects written to output file: %ld\n\n", primitives);
- printf("Total degenerate triangles removed from scene: %ld\n\n", degenerates);
-
- printf ("X bounding values range from %f to %f\n", min_x, max_x);
- printf ("Y bounding values range from %f to %f\n", min_y, max_y);
- printf ("Z bounding values range from %f to %f\n", min_z, max_z);
- printf("\n\t\t\t--- DXF Stats ---\n");
- printf("3D Faces = \t%ld\tTriangles = \t%ld\tPoints = \t%ld\n",num_3dfaces,num_triangles,num_points);
- printf("3D Lines = \t%ld\tCircles = \t%ld\tSolids = \t%ld\n",num_3dlines,num_circles,num_solids);
- printf("Lines = \t%ld\tTraces = \t%ld\n",num_lines,num_traces);
- exit(0);
- }
-
-
- int getline() /* read a group code and the next line from infile */
- {
- fgets(linbuf, BUFSIZE, infile); /* get a line from .DXF */
- if (feof(infile))
- return(1);
- sscanf(linbuf, "%3d", &groupcode); /* scan out group code */
- fgets(linbuf, BUFSIZE, infile); /* get a line from .DXF */
- if (feof(infile))
- return(1);
- return(0);
- }
-
- void writeobj() /* dump out current object we should have all info on */
- {
- if (strstr(curobj, "LINE")) /* a VERY skinny triangle! */
- {
- if (xcoords[0] == xcoords[1] && ycoords[0] == ycoords[1] && zcoords[0] == zcoords[1])
- {
- degenerates++;
- return;
- }
-
- fprintf(outfile, " OBJECT\n");
- fprintf(outfile, " TRIANGLE <%1.06f %1.06f %1.06f> <%1.06f %1.06f %1.06f> <%1.06f %1.06f %1.06f> END_TRIANGLE\n", xcoords[0], ycoords[0], zcoords[0], xcoords[1], ycoords[1], zcoords[1], xcoords[1]+0.01, ycoords[1], zcoords[1]);
- finishobj(curcolor);
- num_lines++;
- return;
- }
- else if (strstr(curobj, "POINT")) /* an itty, bitty sphere! */
- {
- fprintf(outfile, " OBJECT\n");
- fprintf(outfile, " SPHERE <%1.06f %1.06f %1.06f> 0.1 END_SPHERE\n", xcoords[0], ycoords[0], zcoords[0]);
- finishobj(curcolor);
- num_points++;
- return;
- }
- else if (strstr(curobj, "CIRCLE")) /* a VERY short cylinder! */
- {
- fprintf(outfile, " OBJECT\n");
- fprintf(outfile, " INTERSECTION\n");
- fprintf(outfile, " QUADRIC Cylinder_Z SCALE <%1.06f %1.06f %1.06f> END_QUADRIC\n", doubles[0], doubles[0], doubles[0]);
- fprintf(outfile, " PLANE <0.0 0.0 1.0> 0.1 END_PLANE\n");
- fprintf(outfile, " PLANE <0.0 0.0 -1.0> 0.1 END_PLANE\n");
- fprintf(outfile, " END_INTERSECTION\n");
- fprintf(outfile, " TRANSLATE <%1.06f %1.06f %1.06f>\n", xcoords[0], ycoords[0], zcoords[0]);
- finishobj(curcolor);
- num_circles++;
- return;
- }
- else if (strstr(curobj, "ARC")) /* not implemented for now */
- {
- return;
- }
- else if (strstr(curobj, "TRACE")) /* 2 back-to-back triangles */
- {
- if (checkdegen(0, 1, 2))
- {
- degenerates++;
- return;
- }
-
- fprintf(outfile, " OBJECT\n");
- fprintf(outfile, " TRIANGLE <%1.06f %1.06f %1.06f> <%1.06f %1.06f %1.06f> <%1.06f %1.06f %1.06f> END_TRIANGLE\n", xcoords[0], ycoords[0], zcoords[0], xcoords[1], ycoords[1], zcoords[1], xcoords[2], ycoords[2], zcoords[2]);
- num_traces++;
- finishobj(curcolor);
-
- if (checkdegen(0, 3, 2))
- {
- degenerates++;
- return;
- }
-
- fprintf(outfile, " OBJECT\n");
- fprintf(outfile, " TRIANGLE <%1.06f %1.06f %1.06f> <%1.06f %1.06f %1.06f> <%1.06f %1.06f %1.06f> END_TRIANGLE\n", xcoords[0], ycoords[0], zcoords[0], xcoords[3], ycoords[3], zcoords[3], xcoords[2], ycoords[2], zcoords[2]);
- finishobj(curcolor);
-
- return;
- }
- else if (strstr(curobj, "SOLID")) /* 1 or 2 triangles */
- {
- if (checkdegen(0, 1, 2))
- {
- degenerates++;
- return;
- }
-
- fprintf(outfile, " OBJECT\n");
- fprintf(outfile, " TRIANGLE <%1.06f %1.06f %1.06f> <%1.06f %1.06f %1.06f> <%1.06f %1.06f %1.06f> END_TRIANGLE\n", xcoords[0], ycoords[0], zcoords[0], xcoords[1], ycoords[1], zcoords[1], xcoords[2], ycoords[2], zcoords[2]);
- finishobj(curcolor);
- num_solids++;
- if (xcoords[2] == xcoords[3] && ycoords[2] == ycoords[3] && zcoords[2] == zcoords[3])
- return; /* one triangle was enough... */
-
- if (checkdegen(0, 3, 2))
- {
- degenerates++;
- return;
- }
-
- fprintf(outfile, " OBJECT\n");
- fprintf(outfile, " TRIANGLE <%1.06f %1.06f %1.06f> <%1.06f %1.06f %1.06f> <%1.06f %1.06f %1.06f> END_TRIANGLE\n", xcoords[0], ycoords[0], zcoords[0], xcoords[3], ycoords[3], zcoords[3], xcoords[2], ycoords[2], zcoords[2]);
- finishobj(curcolor);
- return;
- }
- else if (strstr(curobj, "TEXT")) /* not implemented for now */
- {
- return;
- }
- else if (strstr(curobj, "SHAPE")) /* these look very hard */
- {
- return;
- }
- else if (strstr(curobj, "BLOCK")) /* these look very hard */
- {
- return;
- }
- else if (strstr(curobj, "ENDBLK")) /* these look very hard */
- {
- return;
- }
- else if (strstr(curobj, "INSERT")) /* these look very hard */
- {
- return;
- }
- else if (strstr(curobj, "ATTDEF")) /* not implemented for now */
- {
- return;
- }
- else if (strstr(curobj, "ATTRIB")) /* not implemented for now */
- {
- return;
- }
- else if (strstr(curobj, "POLYLINE")) /* these look fairly hard */
- {
- return;
- }
- else if (strstr(curobj, "VERTEX")) /* these look fairly hard */
- {
- return;
- }
- else if (strstr(curobj, "SEQEND")) /* these look fairly hard */
- {
- return;
- }
- else if (strstr(curobj, "3DLINE")) /* a VERY skinny triangle! */
- {
- if (xcoords[0] == xcoords[1] && ycoords[0] == ycoords[1] && zcoords[0] == zcoords[1])
- {
- degenerates++;
- return;
- }
-
- fprintf(outfile, " OBJECT\n");
- fprintf(outfile, " TRIANGLE <%1.06f %1.06f %1.06f> <%1.06f %1.06f %1.06f> <%1.06f %1.06f %1.06f> END_TRIANGLE\n", xcoords[0], ycoords[0], zcoords[0], xcoords[1], ycoords[1], zcoords[1], xcoords[1]+0.1, ycoords[1], zcoords[1]);
- finishobj(curcolor);
- num_3dlines++;
-
- return;
- }
- else if (strstr(curobj, "3DFACE")) /* 1 or 2 triangles */
- {
- if (checkdegen(0, 1, 2))
- {
- degenerates++;
- return;
- }
-
- fprintf(outfile, " OBJECT\n");
- fprintf(outfile, " TRIANGLE <%1.06f %1.06f %1.06f> <%1.06f %1.06f %1.06f> <%1.06f %1.06f %1.06f> END_TRIANGLE\n", xcoords[0], ycoords[0], zcoords[0], xcoords[1], ycoords[1], zcoords[1], xcoords[2], ycoords[2], zcoords[2]);
- finishobj(curcolor);
- num_3dfaces++;
- if (xcoords[2] == xcoords[3] && ycoords[2] == ycoords[3] && zcoords[2] == zcoords[3])
- return; /* one triangle was enough... */
-
- if (checkdegen(0, 3, 2))
- {
- degenerates++;
- return;
- }
-
- fprintf(outfile, " OBJECT\n");
- fprintf(outfile, " TRIANGLE <%1.06f %1.06f %1.06f> <%1.06f %1.06f %1.06f> <%1.06f %1.06f %1.06f> END_TRIANGLE\n", xcoords[0], ycoords[0], zcoords[0], xcoords[3], ycoords[3], zcoords[3], xcoords[2], ycoords[2], zcoords[2]);
- finishobj(curcolor);
- return;
- }
- else if (strstr(curobj, "DIMENSION")) /* not implemented for now */
- {
- return;
- }
- return; /* no current object defined... */
- }
-
- void finishobj(color) /* conclude a DKB-style object definition */
- int color;
- {
- double red, green, blue;
-
- lookupcolor(color, &red, &green, &blue);
- fprintf(outfile, " TEXTURE Dull\n"); /* default surf. */
- fprintf(outfile, " COLOR RED %1.06f GREEN %1.06f BLUE %1.06f\n", red, green, blue);
- fprintf(outfile, " END_TEXTURE\n"); /* default surf. */
- fprintf(outfile, " END_OBJECT\n\n");
- printf("."); /* activity echo (happy dots) */
- primitives++; /* count another output file primitive */
- }
-
- void lookupcolor(color, red, green, blue) /* basic AutoCAD 9-color pallette */
- int color;
- double *red, *green, *blue;
- {
- switch (color)
- {
- case 0: /* black */
- *red = *green = *blue = 0.0;
- break;
- case 1: /* red */
- *red = 1.0;
- *blue = *green = 0.0;
- break;
- case 2: /* yellow */
- *red = *green = 1.0;
- *blue = 0.0;
- break;
- case 3: /* green */
- *green = 1.0;
- *red = *blue = 0.0;
- break;
- case 4: /* cyan */
- *blue = *green = 1.0;
- *red = 0.0;
- break;
- case 5: /* blue */
- *blue = 1.0;
- *red = *green = 0.0;
- break;
- case 6: /* magenta */
- *blue = *red = 1.0;
- *green = 0.0;
- break;
- case 8: /* dk. grey */
- *red = *green = *blue = 0.5;
- break;
- case 9: /* lt. grey */
- *red = *green = *blue = 0.75;
- break;
- case 7: /* white */
- default: /* make anything else white (?) */
- *red = *green = *blue = 1.0;
- }
- return;
- }
-
- int checkdegen(a, b, c) /* check for degenerate triangle structure */
- int a, b, c;
- {
- if (
- (xcoords[a] == xcoords[b] &&
- ycoords[a] == ycoords[b] &&
- zcoords[a] == zcoords[b]) ||
- (xcoords[b] == xcoords[c] &&
- ycoords[b] == ycoords[c] &&
- zcoords[b] == zcoords[c]) ||
- (xcoords[a] == xcoords[c] &&
- ycoords[a] == ycoords[c] &&
- zcoords[a] == zcoords[c]))
- return(1);
- return(0);
- }
-